//  Set a global variable for running ajax requests.  This will let us cancel a call before starting another one.
var runningRequest = false;

var success_dialog = '<div style="display:none;" class="response" title="Your email has been sent"><p>Thanks.<br>We will get back to you as soon as possible.</p></div>';
var no_body_dialog = '<div style="display:none;" class="response" title="Empty email"><p>Your email could not be sent because the body is empty.  Please try again.</p></div>';
var not_logged_in_dialog = '<div style="display:none;" class="response" title="Not logged in"><p>You must <a href="/auth">sign in</a> to be able to send emails.</p></div>';

// Wait until the document is loaded and ready before we apply our jQuery code
$(document).ready(
		function() {

			// Set the framerate for animations. The default is 13, but higher
			// values provide smoother animations
			jQuery.fx.interval = 29;

			// Disable the normal submit function of the form that the joke
			// processing is embedded in
			$('#form_194508').submit(function(e) {
				e.preventDefault();
			});

			// Bind the "get another fact" button to the getJoke function
			$('#saveForm').bind('click', getJoke);

			// Bind the "Post to Buzz" button for logged in users to the
			// postToBuzz function
			$('#post_to_buzz').bind('click', postToBuzz);

			// Bind the "Post to Buzz" button for non authorized users to the
			// postToBuzzNonUser function
			$('#post_to_buzz_non_user').bind('click', postToBuzzNonUser);

			// Call getActivityStream to retrieve the latest Buzz posts made
			// with this app, and display the 4 most recent at the bottom of the
			// page.
			getActivityStream();

			// Repeat the call to getActivityStream every 3 minutes to make sure
			// it stays fresh.
			var intervalID = setInterval(function() {
				getActivityStream();
			}, 300000);

			// Turn the email form into a jQuery UI modal dialog
			$("#form_196054").dialog(
					{
						autoOpen : false,
						height : 400,
						width : 600,
						modal : true,
						buttons : {
							"Send" : function() {

								// Post the serialized version of the form to
								// /sendemail.
								// That will pass all form variables to the
								// page.
								$.post('/sendemail', $("#form_196054")
										.serialize(), function(data) {

									// Clear any response dialogs that may exist
									$('.response').remove();

									// If the email was successful, attach the
									// success dialog div, which is hidden by
									// default. Then close the email form, and
									// show the success dialog.
									if (data == 'success') {
										$('body').append(success_dialog);
										$("#form_196054").dialog("close");
										$('.response').dialog();
									}

									// If the email was successful, attach the
									// no body dialog div, which is hidden by
									// default. Leave the dialog form open, and
									// show the no body dialog.
									if (data == 'noBody') {
										$('body').append(no_body_dialog);
										$('.response').dialog();
									}

									// If the email was successful, attach the
									// not logged in dialog div, which is hidden
									// by default. Leave the dialog form open,
									// and show the not logged in dialog.
									if (data == 'notLoggedIn') {
										$('body').append(not_logged_in_dialog);
										$('.response').dialog();
									}

								});

							},
							Cancel : function() {

								// close the dialog when the Close button is
								// pressed
								$(this).dialog("close");
							}
						},
						close : function() {

						}
					});

			// When the email admin link is clicked, prevent it from refreshing
			// the page with a # at the end
			// Then open the email dialog.
			$("#email_admin").click(function(e) {
				e.preventDefault();
				$("#form_196054").dialog("open");
			});
		});

/**
 * This function gets a JSON array of buzz posts (50 by default). Unfortunately
 * the array it gets is sorted by relevancy or something. It then sorts them by
 * date, and publishes the 4 most recent to the page
 * 
 */
function getActivityStream() {

	// Start with an empty string that will be filled with html to be added to
	// the DOM later
	var resultHtml = '';

	// Show the loading gif to indicate that something is happening
	// Also hide the "Latest Buzz posts" text since they occupy the same
	// territory.
	$('#show_feed span').fadeOut('fast', function() {
		$('#show_feed img').fadeIn('fast');
	});

	// Send our get request. It doesn't really need the getStream variable, it
	// is just there as a placeholder
	request = $
			.get(
					'recentactivities.json',
					{
						getStream : 'true'
					},
					function(data) {
						runningRequest = false;

						// Get the id attribute of the first post already on the
						// screen
						var firstId = $('.result').first().attr('id');

						// Sort the incoming JSON array by date descending
						var sorted = $(data.items).sort(sortDateDesc);

						// Only proceed if the first post already on the page is
						// not equal to the first post in the JSON array.
						// This way, there is no unnecessary flashing if there
						// are no new posts to show.
						if (firstId != sorted[0].id) {

							// Loop through the sorted array
							$
									.each(
											sorted,
											function(i, item) {

												// Get just the joke from the
												// post, stripping away the link
												// because all the links are the
												// same, and they all point to
												// this page.
												var joke = item.object.content
														.slice(
																0,
																item.object.content
																		.indexOf("<br />"));

												// If we have reached the 4th
												// entry, break out of the loop.
												// This keeps us from adding 50
												// entries to the page
												if (i === 4) {
													return false;
												}

												// Start appending to the
												// resultHtml string, adding all
												// the html needed to show one
												// post
												// Set up some nice striping by
												// flipping the class between
												// even and odd respectively
												if (isEven(i)) {
													resultHtml += '<div id="'+ item.id + '" class="result boxShadow even">\n';
												} else {
													resultHtml += '<div id="' + item.id + '" class="result boxShadow odd">\n';
												}

												resultHtml += '<h3 class="profile-title"><a class="profile-link" href="' + item.actor.profileUrl + '">\n';
												resultHtml += (item.actor.thumbnailUrl) ? '<img class="profile-photo boxShadow" src="' + item.actor.thumbnailUrl + '">' : '<img class="profile-photo boxShadow" src="/img/generic_person.jpg">';
												resultHtml += item.actor.name + '</a></h3>\n';
												resultHtml += '<p class="feed-content">' + joke + '</p>\n';
												resultHtml += '</div>\n';

											});

							// Once the resultHtml string has been built Fade
							// the stream div out so we can modify it and fade
							// it back in gracefully.
							$('div#stream').fadeOut('fast', function() {

								// Set the content of the stream div to
								// resultHtml
								$('div#stream').html(resultHtml);

								// Show the more posts link. This link is
								// already in the footer of the page, and just
								// points to the same search in Buzz within
								// gmail
								$('.more-link').fadeIn('fast');

								// Fade the stream div back in now that it has
								// been updated.
								$('div#stream').fadeIn('fast');

								// Switch the loading gif out with the text
								// "Latest Buzz posts" to indicate that we are
								// done processing
								$('#show_feed img').fadeOut('fast', function() {
									$('#show_feed span').fadeIn('fast');
								});
							});
						} else {

							// If we aren't updating the html, just hide the
							// loading gif, and show "Latest Buzz posts"
							$('#show_feed img').fadeOut('fast', function() {
								$('#show_feed span').fadeIn('fast');
							});
						}

					});
}

/**
 * This function posts to Buzz for already logged in users. It sends the joke to
 * the postactivity servlet and gets back either the user's profile url, or
 * "failed"
 */
function postToBuzz() {

	// Get the joke text from the currently displayed joke on the page
	var jokeText = $('#joke_text').text();

	// Show the loader spinner
	$('.loader').fadeIn('fast');

	// Start our get request, and post the joke as the "joke" parameter
	request = $.get('postactivity', {
		joke : jokeText
	}, function(data) {
		runningRequest = false;

		// As long as it didn't fail
		if (data !== "failed") {

			// Disable the Post to Buzz button since they just did this one.
			$('#post_to_buzz').attr('disabled', 'disabled').addClass(
					"disabled-button");

			// Show a message stating that they posted to buzz, and give them a
			// link to their profile.
			$('#buzz_response')
					.html(
							'Posted to buzz <a href="' + data
									+ '">My Buzz Profile</a>').removeClass(
							"error").addClass("success");

		} else {

			// If it did fail, show them that there was an error
			$('#buzz_response').text("There was an error posting to Buzz")
					.addClass("error").removeClass("success");
		}

		// Hide the loading spinner
		$('.loader').fadeOut('fast');

		// Show the repsonse (either error or success)
		$('#buzz_response').fadeIn('fast');

		// Reload the activity stream so their post will show up on top.
		getActivityStream();

	});
}

/**
 * This function just opens a popup window to allow users to post to Buzz if
 * they are not logged in It pulls the joke that is currently onscreen and
 * passes it to Buzz
 */
function postToBuzzNonUser() {
	var jokeText = $('#joke_text').text();

	window.open("http://www.google.com/buzz/post?" + "message=" + jokeText
			+ "&url=http://appology-chuck-norris.appspot.com", "_blank",
			"resizable=0,scrollbars=0,width=690,height=415");

}

/**
 * This function gets a fresh formatted joke from the betterthanchuck servlet
 * and injects it into the page.
 */
function getJoke() {
	if (runningRequest) {
		request.abort();
	}

	// Show the loader
	$('.loader').fadeIn('fast');
	runningRequest = true;

	// Start the get request
	request = $.get('betterthanchuck', {
		random : 'true'
	}, function(data) {
		runningRequest = false;

		// Fade out the joke that is currently on the page
		$('#joke_text').fadeOut(
				'fast',
				function() {

					// Put the joke we just got into the page
					$('#joke_text').html(data);

					// Reenable the post to buzz button so the user can post
					// this new joke if they wish
					$('#post_to_buzz').removeAttr('disabled').removeClass(
							"disabled-button");

					// Hide the message about successfully posting the last
					// joke, and remove any success or error classes it may have
					$('#buzz_response').fadeOut('fast', function() {
						$('#buzz_response').removeClass("success error");
					});

					// Hide the loading spinner
					$('.loader').fadeOut('fast');

					// Show the new joke
					$('#joke_text').fadeIn('fast');

				});
	});
}

/**
 * Utility functions
 */

/**
 * Returns true if a number is even
 * 
 * @param someNumber
 * @returns
 */
var isEven = function(someNumber) {
	return (someNumber % 2 == 0) ? true : false;
};

/**
 * Sort an array on given arguments. use array.sort(arg);
 */
jQuery.fn.sort = function() {
	return this.pushStack([].sort.apply(this, arguments), []);
};

/**
 * Given two objects with a published date, returns 0 if equal, 1 if a is
 * greater, and -1 if b is greater Use this as an argument to jQuery.fn.sort()
 * 
 * @param a
 * @param b
 * @returns
 */
function sortDate(a, b) {
	if (a.published == b.published) {
		return 0;
	}
	return a.published > b.published ? 1 : -1;
};

/**
 * Given two objects with a published date, returns the opposite of sortDate Use
 * this as an argument to jQuery.fn.sort()
 * 
 * @param a
 * @param b
 * @returns
 */
function sortDateDesc(a, b) {
	return sortDate(a, b) * -1;
};